# -*- coding: utf-8 -*-
import hashlib
import json
import random

import requests
import xmltodict

from datetime import datetime
from common.utils import exceptions as err
from common.utils import track_logging
from common.withdraw.model import WITHDRAW_ORDER_STATUS

_LOGGER = track_logging.getLogger('withdraw')

APP_CONF = {
    'MDP5b331461755d7': {
        'API_KEY': 'magicMDP',
        'GATEWAY': 'http://miidowpay.com:8080/merchant/process.php',
        'INFO': '测试环境'
    },
    'MDP5b331118e6553': {
        'API_KEY': 'magicMDP',
        'GATEWAY': 'http://miidowpay.com/merchant/process.php',
        'INFO': 'Diablo'
    },
    'MDP5b39ad724f7a0': {
        'API_KEY': 'magicMDP',
        'GATEWAY': 'http://miidowpay.com/merchant/process.php',
        'INFO': 'Durotar'
    },
    'MDP5d3963d1b761e': {
        'API_KEY': 'magicMDP',
        'GATEWAY': 'http://miidowpay.com/merchant/process.php',
        'INFO': 'loki'
    },
    'MDP5d3964074cfa8': {
        'API_KEY': 'magicMDP',
        'GATEWAY': 'http://miidowpay.com/merchant/process.php',
        'INFO': 'witch'
    },
}


def _get_api_key(app_id):
    return APP_CONF[app_id]['API_KEY']


def _get_gateway(app_id):
    return APP_CONF[app_id]['GATEWAY']


def create_order(order, channel):
    ''' MIIDOW代付下单 '''
    app_id = channel.appid
    data = {
        "request": {
            "method": "reqFundout",
            "merchantId": app_id,
            "receiver": order.pay_account_username,
            "account_number": order.pay_account_num,
            "bank_name": order.pay_account_bank,
            "bank_branch": order.pay_account_bank_subbranch or order.pay_account_bank,
            "reference_number": "",
            "transactionId": str(order.id),
            "amount": order.amount,
        }
    }

    data['request']['sign'] = generate_sign(
        u'magicMDP' + unicode(data['request']['merchantId']) +
        unicode(data['request']['transactionId']) + unicode(data['request']['amount'])
    )
    headers = {'Content-Type': 'application/xml;charset=utf-8'}
    xml_data = (u"xmlStr=" + xmltodict.unparse(data))
    _LOGGER.info("miidow withdraw create order: %s", xml_data)

    # 先设置为未知状态，卡住人工核实
    order.status = WITHDRAW_ORDER_STATUS.THIRD_UNKNOWN
    order.third_type = channel.id
    order.save()

    response = requests.get(_get_gateway(app_id) + '?' + xml_data, headers=headers, timeout=5)
    _LOGGER.info("miidow withdraw create rsp: %s", response.text)
    res_dict = xmltodict.parse(response.text)["response"]
    code = res_dict['returnStatus']['code']
    if int(code) == 001:
        order.status = WITHDRAW_ORDER_STATUS.THIRD
        order.extra_info = response.text
        order.save()
        return True
    else:
        order.status = WITHDRAW_ORDER_STATUS.THIRD_FAIL
        order.extra_info = response.text
        order.save()
        return False


def generate_sign(s):
    _LOGGER.info('sign string: %s' % s)
    m = hashlib.md5()
    m.update(s.encode('utf8'))
    sign = m.hexdigest().lower()
    return sign


def _verify_notify_sign(data):
    sign = data['sign']
    calculated_sign = generate_sign('magicMDP' +
                                    data['merchantId'] + str(data['transactionId']))
    if sign != calculated_sign:
        _LOGGER.info("miidow withdraw sign: %s, calculated sign: %s", sign, calculated_sign)
        raise err.ParamError('miidow sign not pass, data: %s' % data)


def check_bankcard_withdraw_notify(data, order):
    ''' MIIDOW代付回调 '''
    _LOGGER.info('miidow bankcard callback, notify_data : %s ', data)
    _verify_notify_sign(data)
    order_id = data['transactionId']
    trade_status = data['status']
    if not order:
        raise err.ParamError('miidow bankcard withdraw event does not contain valid order ID')

    if trade_status == 'Approved':
        _LOGGER.info('miidow success: %s' % data)
        order.status = WITHDRAW_ORDER_STATUS.DONE
        order.extra_info = json.dumps(data)
        order.third_notify_at = datetime.utcnow()

        order.save()
        return True
    elif trade_status == 'Rejected':
        _LOGGER.info('miidow fail: %s' % data)
        order.status = WITHDRAW_ORDER_STATUS.THIRD_FAIL
        order.extra_info = json.dumps(data)
        order.third_notify_at = datetime.utcnow()

        order.save()
        return False
    else:
        raise err.ParamError('status invalid')


def query_order(order, channel):
    try:
        app_id = channel.appid
        url = _get_gateway(app_id)
        request_data = {
            "request": {
                "method": "reqTransactionQuery",
                "merchantId": app_id,
                "transactionId": str(order.id)
            }
        }

        request_data['request']['sign'] = generate_sign(
            u'magicMDP' + unicode(request_data['request']['merchantId']) +
            unicode(request_data['request']['transactionId']))

        header = {'Content-Type': 'application/xml;charset=utf-8'}
        xml_response = (u"xmlStr=" + xmltodict.unparse(request_data)).encode('utf-8')
        response = requests.get(url + '?' + xml_response, headers=header, timeout=5)
        _LOGGER.info("miidow Query withdraw : %s,  data: %s, order_id: %s" % (url, xml_response, str(order.id)))

        response_dict = xmltodict.parse(response.text)["response"]
        code = response_dict['returnStatus']['code']
        if int(code) == 001:
            status = str(response_dict['transaction']['status'])
            if status == 'Approved':
                order.status = WITHDRAW_ORDER_STATUS.DONE
            elif status == 'Rejected':
                order.status = WITHDRAW_ORDER_STATUS.REJECTED
            elif status == 'Pending':
                order.status = WITHDRAW_ORDER_STATUS.WAIT
            order.extra_info = json.dumps(response_dict['transaction'])
            order.save()
        else:
            order.status = WITHDRAW_ORDER_STATUS.THIRD_FAIL
            order.extra_info = response.text
            order.save()

    except Exception, e:
        _LOGGER.info('miidow pay Query withdraw fail: %s, %s', e, order.id)
        return False


if __name__ == "__main__":
    ''' MIIDOW代付下单 '''
    app_id = "MDP5b331118e6553"
    data = {
        "request": {
            "method": "reqFundout",
            "merchantId": app_id,
            "receiver": 'test',
            "account_number": '612222211111111',
            "bank_name": 'Bank of China',
            "bank_branch": u'Beijing',
            "reference_number": "",
            "transactionId": random.randint(10000, 99999),
            "amount": 101,
        }
    }

    data['request']['sign'] = generate_sign(
        'magicMDP' + data['request']['merchantId'] + str(data['request']['transactionId']) + str(
            data['request']['amount']))
    headers = {'Content-Type': 'application/xml;charset=utf-8'}
    _LOGGER.info("miidow withdraw create order: %s" % data)
    xml_data = ("xmlStr=" + xmltodict.unparse(data)).encode('utf-8')
    response = requests.get(_get_gateway(app_id) + '?' + xml_data, headers=headers, timeout=5)
    _LOGGER.info("miidow withdraw create rsp: %s", response.text)
    print response.text
    res_dict = xmltodict.parse(response.text)["response"]
    print res_dict['response']['returnStatus']['code']
